﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;

namespace InfonavaEye.util
{
    public class ExeUtil
    {
        public static Process currentProcess = null;

        public static void openExe(string exePath,string exeName)
        {
            try
            {
                using (Process p = new Process())
                {
                    currentProcess = p;
                    p.StartInfo.FileName = exePath;
                    p.StartInfo.UseShellExecute = false;        //是否使用操作系统shell启动
                    p.StartInfo.RedirectStandardInput = false;  //接受来自调用程序的输入信息
                    p.StartInfo.RedirectStandardOutput = true;  //由调用程序获取输出信息
                    p.StartInfo.RedirectStandardError = true;   //重定向标准错误输出
                    p.OutputDataReceived += ((sender, e) =>
                    {
                        Console.WriteLine(exeName + "程序：" + e.Data);
                    });
                    p.ErrorDataReceived += new DataReceivedEventHandler((sender, e) =>
                    {
                        Console.WriteLine(exeName+"程序发生异常：" +e.Data);
                    });

                    p.StartInfo.CreateNoWindow = false;          //不显示程序窗口
                    //p.StartInfo.Arguments = argumentsFortheJarFile;
                    if (!p.Start()) //启动程序
                    {
                        Console.WriteLine(exeName+"程序未能启动");
                        return;
                    }

                    // To avoid deadlocks, use an asynchronous read operation on at least one of the streams.  
                    p.BeginErrorReadLine();
                    p.BeginOutputReadLine();

                    //获取cmd窗口的输出信息
                   /* while (!p.StandardOutput.EndOfStream)
                    {
                        string oneLine = p.StandardOutput.ReadLine();

                        Console.WriteLine(exeName + "程序：" + oneLine);
                    }
                    p.StandardOutput.Close();*/

                    //p.WaitForExit();//等待程序执行完退出进程
                    //p.Close();

                   /* currentProcess = _exeProcess;
                    _exeProcess.StartInfo.FileName = exePath;
                    //_exeProcess.StartInfo.WorkingDirectory = baseDir + "\\" + "socket_multi_process_server";
                    //_exeProcess.StartInfo.Arguments = args;

                    _exeProcess.StartInfo.CreateNoWindow = false;  // 不显示窗口
                    //_exeProcess.StartInfo.WorkingDirectory = "";  // 设置工作目录
                    //_exeProcess.StartInfo.Environment.Add("key", "value");  // 添加环境变量

                    // 是否使用 explorer.exe 执行命令。
                    // 如需监听输出，请设置为false，原因如下：
                    // 若为true，那么就基本等同下面两行代码
                    // _exeProcess.StartInfo.FileName = "explorer.exe"
                    // _exeProcess.StartInfo.Arguments = exeName;
                    _exeProcess.StartInfo.UseShellExecute = false;

                    // 启用标准输出，异常输出监听支持
                    _exeProcess.StartInfo.RedirectStandardOutput = true;
                    _exeProcess.StartInfo.RedirectStandardError = true;

                    // 启用 Exited 事件支持
                    _exeProcess.EnableRaisingEvents = true;

                    _exeProcess.OutputDataReceived += ExeProcess_OutputDataReceived;
                    _exeProcess.ErrorDataReceived += ExeProcess_ErrorDataReceived;
                    _exeProcess.Exited += ExeProcess_Exited;

                    _exeProcess.Start();

                    // 开启消息监听
                    _exeProcess.BeginOutputReadLine();
                    _exeProcess.BeginErrorReadLine();*/

                    // {
                    // 启用标准输入流支持
                    // _exeProcess.StartInfo.RedirectStandardInput = true;

                    // 标准输入流的写入方法
                    // _exeProcess.StandardInput.Write("");
                    // _exeProcess.StandardInput.WriteLine("");
                    // }

                    /* p.StartInfo.FileName = exePath;//需要执行的文件路径
                     p.StartInfo.UseShellExecute = false; //必需
                     p.StartInfo.WorkingDirectory = Directory.GetCurrentDirectory() + "\\" + "socket_multi_process_server";
                     p.StartInfo.RedirectStandardOutput = false;//输出参数设定
                     p.StartInfo.RedirectStandardInput = false;//传入参数设定
                     //p.StartInfo.CreateNoWindow = true;
                     //p.StartInfo.Arguments = "2 3";//参数以空格分隔，如果某个参数为空，可以传入””
                     p.Start();
                     p.WaitForExit();//关键，等待外部程序退出后才能往下执行
                     //string output = p.StandardOutput.ReadToEnd();
                     //Console.Write(output);//输出*/

                }
            }
            catch (Exception ex)
            {
                Console.WriteLine("打开exe发生错误：{0}", ex.StackTrace);
            }
        }

        private static void ExeProcess_OutputDataReceived(object sender, DataReceivedEventArgs e)
        {
            Console.WriteLine( "程序输出:" + e.Data);
        }

        private static void ExeProcess_ErrorDataReceived(object sender, DataReceivedEventArgs e)
        {
            Console.WriteLine("程序报错:" + e.Data);
        }

        private static void ExeProcess_Exited(object sender, EventArgs e)
        {
            // 取消消息监听
            currentProcess.CancelOutputRead();
            currentProcess.CancelErrorRead();

            currentProcess.OutputDataReceived -= ExeProcess_OutputDataReceived;
            currentProcess.ErrorDataReceived -= ExeProcess_ErrorDataReceived;
            currentProcess.Exited -= ExeProcess_Exited;

            currentProcess.Close();
            currentProcess = null;
        }

        public static void closeExe()
        {
            try
            {
                if (currentProcess != null)
                {
                    //ExeProcess_Exited(null, null);
                    //currentProcess.CloseMainWindow();
                    //currentProcess.CancelOutputRead();
                    //currentProcess.CancelErrorRead();
                    currentProcess.StandardOutput.Close();
                    currentProcess.Close();
                    //currentProcess.Kill();
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine("关闭exe发生错误：{0}", ex.StackTrace);
                try
                {
                    currentProcess.Kill();
                }
                catch (Exception e)
                {
                    Console.WriteLine("杀死exe发生错误：{0}", e.StackTrace);
                }
            }
        }

    }
}
